package org.jradweb.tools.generator.maven;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;

public abstract class BaseMojo extends AbstractMojo {
	/**
	 * @parameter expression="${project.build.directory}"
	 */
	protected File buildPath;

	/**
	 * @parameter expression="${basedir}"
	 */
	protected File baseDir;

	/**
	 * @parameter expression="${project}"
	 */
	protected MavenProject project;

	/**
	 * @parameter expression="${project.groupId}"
	 */
	protected String groupId;

	/**
	 * @parameter expression="${project.artifactId}"
	 */
	protected String artifactId;

	public void execute() throws MojoExecutionException, MojoFailureException {
		this.getLog().info("project: " + project.getArtifactId());
		this.getLog().info("basedir: " + this.baseDir.getAbsolutePath());
		try {
			List classpathElements = this.getCompileClasspathElements();
			List deps = project.getDependencies();
			this.getLog().info("deps");
		} catch (DependencyResolutionRequiredException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		Thread currentThread = Thread.currentThread();
		ClassLoader oldClassLoader = currentThread.getContextClassLoader();

		try {
			currentThread.setContextClassLoader(getClassLoader());

			doExecute();
		} finally {
			currentThread.setContextClassLoader(oldClassLoader);
		}
	}

	protected abstract void doExecute() throws MojoExecutionException,
			MojoFailureException;

	public MavenProject getProject() {
		return project;
	}

	public File getBasedir() {
		return baseDir;
	}

	public void setProject(MavenProject project) {
		this.project = project;
	}

	public void setBasedir(File basedir) {
		this.baseDir = basedir;
	}

	private ClassLoader getClassLoader() {
		try {
			List classpathElements = project.getCompileClasspathElements();
			classpathElements.add(project.getBuild().getOutputDirectory());
			classpathElements.add(project.getBuild().getTestOutputDirectory());
			this.getLog().info("project :" + project.getArtifactId());
			URL urls[] = new URL[classpathElements.size()];
			for (int i = 0; i < classpathElements.size(); ++i) {
				urls[i] = new File((String) classpathElements.get(i)).toURL();
				this.getLog().info("class load url: " + urls[i]);
			}
			ClassLoader loader = new URLClassLoader(urls, this.getClass()
					.getClassLoader());
			
			return loader;
		} catch (Exception e) {
			getLog().debug("Couldn't get the classloader.");
			return this.getClass().getClassLoader();
		}
	}

	public List getCompileClasspathElements()
			throws DependencyResolutionRequiredException {
		List list = new ArrayList(project.getArtifacts().size());

		list.add(project.getBuild().getOutputDirectory());

		for (Iterator i = project.getArtifacts().iterator(); i.hasNext();) {
			Artifact a = (Artifact) i.next();

			if (a.getArtifactHandler().isAddedToClasspath()) {
				// TODO: let the scope handler deal with this
				if (Artifact.SCOPE_COMPILE.equals(a.getScope())
						|| Artifact.SCOPE_PROVIDED.equals(a.getScope())
						|| Artifact.SCOPE_SYSTEM.equals(a.getScope())) {
					// project.addArtifactPath(a, list);
				}
			}
		}
		return list;
	}
}
